home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gdevpsf2.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  49.9 KB  |  1,671 lines

  1. /* Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gdevpsf2.c,v 1.7.2.2 2000/11/21 05:46:25 rayjj Exp $ */
  20. /* Write an embedded CFF font with either Type 1 or Type 2 CharStrings */
  21. #include "math_.h"        /* for fabs */
  22. #include "memory_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gsccode.h"
  26. #include "gscrypt1.h"
  27. #include "gsmatrix.h"
  28. #include "gsutil.h"
  29. #include "gxfixed.h"
  30. #include "gxfont.h"
  31. #include "gxfont1.h"
  32. #include "gxfcid.h"
  33. #include "stream.h"
  34. #include "sfilter.h"
  35. #include "gdevpsf.h"
  36.  
  37. /* Define additional opcodes used in Dicts, but not in CharStrings. */
  38. #define CD_LONGINT 29
  39. #define CD_REAL 30
  40.  
  41. /* Define the count of standard strings. */
  42. #define NUM_STD_STRINGS 391
  43.  
  44. /* Define whether or not to skip writing an empty Subrs Index. */
  45. #define SKIP_EMPTY_SUBRS
  46.  
  47. /* Define the structure for the string table. */
  48. typedef struct cff_string_item_s {
  49.     gs_const_string key;
  50.     int index1;        /* index + 1, 0 means empty */
  51. } cff_string_item_t;
  52. typedef struct cff_string_table_s {
  53.     cff_string_item_t *items;
  54.     int count;
  55.     int size;
  56.     uint total;
  57.     int reprobe;
  58. } cff_string_table_t;
  59.  
  60. /* Define the state of the CFF writer. */
  61. typedef struct cff_writer_s {
  62.     int options;
  63.     stream *strm;
  64.     gs_font_base *pfont;    /* type1 or cid0 */
  65.     glyph_data_proc_t glyph_data;
  66.     int offset_size;
  67.     long start_pos;
  68.     cff_string_table_t std_strings;
  69.     cff_string_table_t strings;
  70. } cff_writer_t;
  71. typedef struct cff_glyph_subset_s {
  72.     psf_outline_glyphs_t glyphs;
  73.     int num_encoded;        /* glyphs.subset_data[1..num_e] are encoded */
  74.     int num_encoded_chars;    /* Encoding has num_e_chars defined entries */
  75. } cff_glyph_subset_t;
  76.  
  77. /* ---------------- Output utilities ---------------- */
  78.  
  79. /* ------ String tables ------ */
  80.  
  81. /* Initialize a string table. */
  82. private void
  83. cff_string_table_init(cff_string_table_t *pcst, cff_string_item_t *items,
  84.               int size)
  85. {
  86.     int reprobe = 17;
  87.  
  88.     memset(items, 0, size * sizeof(*items));
  89.     pcst->items = items;
  90.     pcst->count = 0;
  91.     pcst->size = size;
  92.     while (size % reprobe == 0 && reprobe != 1)
  93.     reprobe = (reprobe * 2 + 1) % size;
  94.     pcst->total = 0;
  95.     pcst->reprobe = reprobe;
  96. }
  97.  
  98. /* Add a string to a string table. */
  99. private int
  100. cff_string_add(cff_string_table_t *pcst, const byte *data, uint size)
  101. {
  102.     int index;
  103.  
  104.     if (pcst->count >= pcst->size)
  105.     return_error(gs_error_limitcheck);
  106.     index = pcst->count++;
  107.     pcst->items[index].key.data = data;
  108.     pcst->items[index].key.size = size;
  109.     pcst->total += size;
  110.     return index;
  111. }
  112.  
  113. /* Look up a string, optionally adding it. */
  114. /* Return 1 if the string was added. */
  115. private int
  116. cff_string_index(cff_string_table_t *pcst, const byte *data, uint size,
  117.          bool enter, int *pindex)
  118. {
  119.     /****** FAILS IF TABLE FULL AND KEY MISSING ******/
  120.     int j = (size == 0 ? 0 : data[0] * 23 + data[size - 1] * 59 + size);
  121.     int index;
  122.  
  123.     while ((index = pcst->items[j %= pcst->size].index1) != 0) {
  124.     --index;
  125.     if (!bytes_compare(pcst->items[index].key.data,
  126.                pcst->items[index].key.size, data, size)) {
  127.         *pindex = index;
  128.         return 0;
  129.     }
  130.     j += pcst->reprobe;
  131.     }
  132.     if (!enter)
  133.     return_error(gs_error_undefined);
  134.     index = cff_string_add(pcst, data, size);
  135.     if (index < 0)
  136.     return index;
  137.     pcst->items[j].index1 = index + 1;
  138.     *pindex = index;
  139.     return 1;
  140. }
  141.  
  142. /* Get the SID for a string or a glyph. */
  143. private int
  144. cff_string_sid(cff_writer_t *pcw, const byte *data, uint size)
  145. {
  146.     int index;
  147.     int code = cff_string_index(&pcw->std_strings, data, size, false, &index);
  148.  
  149.     if (code < 0) {
  150.     code = cff_string_index(&pcw->strings, data, size, true, &index);
  151.     if (code < 0)
  152.         return code;
  153.     index += NUM_STD_STRINGS;
  154.     }
  155.     return index;
  156. }
  157. private int
  158. cff_glyph_sid(cff_writer_t *pcw, gs_glyph glyph)
  159. {
  160.     uint len;
  161.     const byte *chars = (const byte *)
  162.     pcw->pfont->procs.callbacks.glyph_name(glyph, &len);
  163.  
  164.     if (chars == 0)
  165.     return_error(gs_error_rangecheck);
  166.     return cff_string_sid(pcw, chars, len);
  167. }
  168.  
  169. /* ------ Low level ------ */
  170.  
  171. private void
  172. put_card16(cff_writer_t *pcw, uint c16)
  173. {
  174.     sputc(pcw->strm, (byte)(c16 >> 8));
  175.     sputc(pcw->strm, (byte)c16);
  176. }
  177. private int
  178. offset_size(uint offset)
  179. {
  180.     int size = 1;
  181.  
  182.     while (offset > 255)
  183.     offset >>= 8, ++size;
  184.     return size;
  185. }
  186. private void
  187. put_offset(cff_writer_t *pcw, int offset)
  188. {
  189.     int i;
  190.  
  191.     for (i = pcw->offset_size - 1; i >= 0; --i)
  192.     sputc(pcw->strm, (byte)(offset >> (i * 8)));
  193. }
  194. private int
  195. put_bytes(stream * s, const byte *ptr, uint count)
  196. {
  197.     uint used;
  198.  
  199.     sputs(s, ptr, count, &used);
  200.     return (int)used;
  201. }
  202.  
  203. /* ------ Data types ------ */
  204.  
  205. #define CE_OFFSET 32
  206. private void
  207. cff_put_op(cff_writer_t *pcw, int op)
  208. {
  209.     if (op >= CE_OFFSET) {
  210.     sputc(pcw->strm, cx_escape);
  211.     sputc(pcw->strm, op - CE_OFFSET);
  212.     } else
  213.     sputc(pcw->strm, op);
  214. }
  215. private void
  216. cff_put_int(cff_writer_t *pcw, int i)
  217. {
  218.     stream *s = pcw->strm;
  219.  
  220.     if (i >= -107 && i <= 107)
  221.     sputc(s, (byte)(i + 139));
  222.     else if (i <= 1131 && i >= 0)
  223.     put_card16(pcw, (c_pos2_0 << 8) + i - 108);
  224.     else if (i >= -1131 && i < 0)
  225.     put_card16(pcw, (c_neg2_0 << 8) - i - 108);
  226.     else if (i >= -32768 && i <= 32767) {
  227.     sputc(s, c2_shortint);
  228.     put_card16(pcw, i & 0xffff);
  229.     } else {
  230.     sputc(s, CD_LONGINT);
  231.     put_card16(pcw, i >> 16);
  232.     put_card16(pcw, i & 0xffff);
  233.     }
  234. }
  235. private void
  236. cff_put_int_value(cff_writer_t *pcw, int i, int op)
  237. {
  238.     cff_put_int(pcw, i);
  239.     cff_put_op(pcw, op);
  240. }
  241. private void
  242. cff_put_int_if_ne(cff_writer_t *pcw, int i, int i_default, int op)
  243. {
  244.     if (i != i_default)
  245.     cff_put_int_value(pcw, i, op);
  246. }
  247. private void
  248. cff_put_bool(cff_writer_t *pcw, bool b)
  249. {
  250.     cff_put_int(pcw, (b ? 1 : 0));
  251. }
  252. private void
  253. cff_put_bool_value(cff_writer_t *pcw, bool b, int op)
  254. {
  255.     cff_put_bool(pcw, b);
  256.     cff_put_op(pcw, op);
  257. }
  258. private void
  259. cff_put_real(cff_writer_t *pcw, floatp f)
  260. {
  261.     if (f == (int)f)
  262.     cff_put_int(pcw, (int)f);
  263.     else {
  264.     /* Use decimal representation. */
  265.     char str[50];
  266.     byte b = 0xff;
  267.     const char *p;
  268.  
  269.     sprintf(str, "%g", f);
  270.     sputc(pcw->strm, CD_REAL);
  271.     for (p = str; ; ++p) {
  272.         int digit;
  273.  
  274.         switch (*p) {
  275.         case 0:
  276.         goto done;
  277.         case '.':
  278.         digit = 0xa; break;
  279.         case '-':
  280.         digit = 0xe; break;
  281.         case 'e': case 'E':
  282.         if (p[1] == '-')
  283.             digit = 0xc, ++p;
  284.         else
  285.             digit = 0xb;
  286.         break;
  287.         case '0': case '1': case '2': case '3': case '4':
  288.         case '5': case '6': case '7': case '8': case '9':
  289.         digit = *p - '0';
  290.         break;
  291.         default:        /* can't happen */
  292.         digit = 0xd;    /* invalid */
  293.         break;
  294.         }
  295.         if (b == 0xff)
  296.         b = (digit << 4) + 0xf;
  297.         else {
  298.         sputc(pcw->strm, (b & 0xf0) + digit);
  299.         b = 0xff;
  300.         }
  301.     }
  302.     done:
  303.     sputc(pcw->strm, b);
  304.     }
  305. }
  306. private void
  307. cff_put_real_value(cff_writer_t *pcw, floatp f, int op)
  308. {
  309.     cff_put_real(pcw, f);
  310.     cff_put_op(pcw, op);
  311. }
  312. private void
  313. cff_put_real_if_ne(cff_writer_t *pcw, floatp f, floatp f_default, int op)
  314. {
  315.     if ((float)f != (float)f_default)
  316.     cff_put_real_value(pcw, f, op);
  317. }
  318. private void
  319. cff_put_real_deltarray(cff_writer_t *pcw, const float *pf, int count, int op)
  320. {
  321.     float prev = 0;
  322.     int i;
  323.  
  324.     if (count <= 0)
  325.     return;
  326.     for (i = 0; i < count; ++i) {
  327.     float f = pf[i];
  328.  
  329.     cff_put_real(pcw, f - prev);
  330.     prev = f;
  331.     }
  332.     cff_put_op(pcw, op);
  333. }
  334. private int
  335. cff_put_string(cff_writer_t *pcw, const byte *data, uint size)
  336. {
  337.     int sid = cff_string_sid(pcw, data, size);
  338.  
  339.     if (sid < 0)
  340.     return sid;
  341.     cff_put_int(pcw, sid);
  342.     return 0;
  343. }
  344. private int
  345. cff_put_string_value(cff_writer_t *pcw, const byte *data, uint size, int op)
  346. {
  347.     int code = cff_put_string(pcw, data, size);
  348.  
  349.     if (code >= 0)
  350.     cff_put_op(pcw, op);
  351.     return code;
  352. }
  353. private int
  354. cff_extra_lenIV(const cff_writer_t *pcw, const gs_font_type1 *pfont)
  355. {
  356.     return (pcw->options & WRITE_TYPE2_NO_LENIV ?
  357.         max(pfont->data.lenIV, 0) : 0);
  358. }
  359. private bool
  360. cff_convert_charstrings(const cff_writer_t *pcw, const gs_font_base *pfont)
  361. {
  362.     return (pfont->FontType != ft_encrypted2 &&
  363.         (pcw->options & WRITE_TYPE2_CHARSTRINGS) != 0);
  364. }
  365. private int
  366. cff_put_CharString(cff_writer_t *pcw, const byte *data, uint size,
  367.            gs_font_type1 *pfont)
  368. {
  369.     int lenIV = pfont->data.lenIV;
  370.     stream *s = pcw->strm;
  371.  
  372.     if (cff_convert_charstrings(pcw, (gs_font_base *)pfont)) {
  373.     gs_const_string str;
  374.     int code;
  375.  
  376.     str.data = data;
  377.     str.size = size;
  378.     code = psf_convert_type1_to_type2(s, &str, pfont);
  379.     if (code < 0)
  380.         return code;
  381.     } else if (lenIV < 0 || !(pcw->options & WRITE_TYPE2_NO_LENIV))
  382.     put_bytes(s, data, size);
  383.     else if (size >= lenIV) {
  384.     /* Remove encryption. */
  385.     crypt_state state = crypt_charstring_seed;
  386.     byte buf[50];        /* arbitrary */
  387.     uint left, n;
  388.  
  389.     for (left = lenIV; left > 0; left -= n) {
  390.         n = min(left, sizeof(buf));
  391.         gs_type1_decrypt(buf, data + lenIV - left, n, &state);
  392.     }
  393.     for (left = size - lenIV; left > 0; left -= n) {
  394.         n = min(left, sizeof(buf));
  395.         gs_type1_decrypt(buf, data + size - left, n, &state);
  396.         put_bytes(s, buf, n);
  397.     }
  398.     }
  399.     return 0;
  400. }
  401. private uint
  402. cff_Index_size(uint count, uint total)
  403. {
  404.     return (count == 0 ? 2 :
  405.         3 + offset_size(total + 1) * (count + 1) + total);
  406. }
  407. private void
  408. cff_put_Index_header(cff_writer_t *pcw, uint count, uint total)
  409. {
  410.     put_card16(pcw, count);
  411.     if (count > 0) {
  412.     pcw->offset_size = offset_size(total + 1);
  413.     sputc(pcw->strm, pcw->offset_size);
  414.     put_offset(pcw, 1);
  415.     }
  416. }
  417. private void
  418. cff_put_Index(cff_writer_t *pcw, const cff_string_table_t *pcst)
  419. {
  420.     uint j, offset;
  421.  
  422.     if (pcst->count == 0) {
  423.     put_card16(pcw, 0);
  424.     return;
  425.     }
  426.     cff_put_Index_header(pcw, pcst->count, pcst->total);
  427.     for (j = 0, offset = 1; j < pcst->count; ++j) {
  428.     offset += pcst->items[j].key.size;
  429.     put_offset(pcw, offset);
  430.     }
  431.     for (j = 0; j < pcst->count; ++j)
  432.     put_bytes(pcw->strm, pcst->items[j].key.data, pcst->items[j].key.size);
  433. }
  434.  
  435. /* ---------------- Main code ---------------- */
  436.  
  437. /* ------ Top Dict ------ */
  438.  
  439. /*
  440.  * There are 3 variants of this: Type 1 / Type 2 font, CIDFontType 0
  441.  * CIDFont, and FDArray entry for CIDFont.
  442.  */
  443.  
  444. typedef enum {
  445.     TOP_version = 0,
  446.     TOP_Notice = 1,
  447.     TOP_FullName = 2,
  448.     TOP_FamilyName = 3,
  449.     TOP_Weight = 4,
  450.     TOP_FontBBox = 5,
  451.     TOP_UniqueID = 13,
  452.     TOP_XUID = 14,
  453.     TOP_charset = 15,        /* (offset or predefined index) */
  454. #define charset_ISOAdobe 0
  455. #define charset_Expert 1
  456. #define charset_ExpertSubset 2
  457. #define charset_DEFAULT 0
  458.     TOP_Encoding = 16,        /* (offset or predefined index) */
  459. #define Encoding_Standard 0
  460. #define Encoding_Expert 1
  461. #define Encoding_DEFAULT 0
  462.     TOP_CharStrings = 17,    /* (offset) */
  463.     TOP_Private = 18,        /* (offset) */
  464.     TOP_Copyright = 32,
  465.     TOP_isFixedPitch = 33,
  466. #define isFixedPitch_DEFAULT false
  467.     TOP_ItalicAngle = 34,
  468. #define ItalicAngle_DEFAULT 0
  469.     TOP_UnderlinePosition = 35,
  470. #define UnderlinePosition_DEFAULT (-100)
  471.     TOP_UnderlineThickness = 36,
  472. #define UnderlineThickness_DEFAULT 50
  473.     TOP_PaintType = 37,
  474. #define PaintType_DEFAULT 0
  475.     TOP_CharstringType = 38,
  476. #define CharstringType_DEFAULT 2
  477.     TOP_FontMatrix = 39,    /* default is [0.001 0 0 0.001 0 0] */
  478.     TOP_StrokeWidth = 40,
  479. #define StrokeWidth_DEFAULT 0
  480.     TOP_ROS = 62,
  481.     TOP_CIDFontVersion = 63,
  482. #define CIDFontVersion_DEFAULT 0
  483.     TOP_CIDFontRevision = 64,
  484. #define CIDFontRevision_DEFAULT 0
  485.     TOP_CIDFontType = 65,
  486. #define CIDFontType_DEFAULT 0
  487.     TOP_CIDCount = 66,
  488. #define CIDCount_DEFAULT 8720
  489.     TOP_UIDBase = 67,
  490.     TOP_FDArray = 68,        /* (offset) */
  491.     TOP_FDSelect = 69,        /* (offset) */
  492.     TOP_FontName = 70        /* only used in FDArray "fonts" */
  493. } Top_op;
  494.  
  495. private void
  496. cff_write_Top_common(cff_writer_t *pcw, gs_font_base *pbfont,
  497.              bool full_info)
  498. {
  499.     gs_font_info_t info;
  500.     int code;
  501.  
  502.     info.Flags_requested = FONT_IS_FIXED_WIDTH;
  503.     /* Preset defaults */
  504.     info.members = 0;
  505.     info.Flags = info.Flags_returned = 0;
  506.     info.ItalicAngle = ItalicAngle_DEFAULT;
  507.     info.UnderlinePosition = UnderlinePosition_DEFAULT;
  508.     info.UnderlineThickness = UnderlineThickness_DEFAULT;
  509.     code = pbfont->procs.font_info((gs_font *)pbfont, NULL,
  510.             (full_info ?
  511.              FONT_INFO_FLAGS | FONT_INFO_ITALIC_ANGLE |
  512.              FONT_INFO_UNDERLINE_POSITION |
  513.              FONT_INFO_UNDERLINE_THICKNESS : 0) |
  514.             (FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE |
  515.              FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
  516.                   &info);
  517.     /* (version) */
  518.     if (info.members & FONT_INFO_NOTICE)
  519.     cff_put_string_value(pcw, info.Notice.data, info.Notice.size,
  520.                  TOP_Notice);
  521.     if (info.members & FONT_INFO_FULL_NAME)
  522.     cff_put_string_value(pcw, info.FullName.data, info.FullName.size,
  523.                  TOP_FullName);
  524.     if (info.members & FONT_INFO_FAMILY_NAME)
  525.     cff_put_string_value(pcw, info.FamilyName.data, info.FamilyName.size,
  526.                  TOP_FamilyName);
  527.     /* (Weight) */
  528.     {
  529.     cff_put_real(pcw, pbfont->FontBBox.p.x);
  530.     cff_put_real(pcw, pbfont->FontBBox.p.y);
  531.     cff_put_real(pcw, pbfont->FontBBox.q.x);
  532.     cff_put_real(pcw, pbfont->FontBBox.q.y);
  533.     cff_put_op(pcw, TOP_FontBBox);
  534.     }
  535.     if (uid_is_UniqueID(&pbfont->UID))
  536.     cff_put_int_value(pcw, pbfont->UID.id, TOP_UniqueID);
  537.     else if (uid_is_XUID(&pbfont->UID)) {
  538.     int j;
  539.  
  540.     for (j = 0; j < uid_XUID_size(&pbfont->UID); ++j)
  541.         cff_put_int(pcw, uid_XUID_values(&pbfont->UID)[j]);
  542.     cff_put_op(pcw, TOP_XUID);
  543.     }
  544.     /*
  545.      * Acrobat Reader 3 gives an error if a CFF font includes any of the
  546.      * following opcodes.
  547.      */
  548.     if (!(pcw->options & WRITE_TYPE2_AR3)) {
  549.     if (info.members & FONT_INFO_COPYRIGHT)
  550.         cff_put_string_value(pcw, info.Copyright.data, info.Copyright.size,
  551.                  TOP_Copyright);
  552.     if (info.Flags & info.Flags_returned & FONT_IS_FIXED_WIDTH)
  553.         cff_put_bool_value(pcw, true, TOP_isFixedPitch);
  554.     cff_put_real_if_ne(pcw, info.ItalicAngle, ItalicAngle_DEFAULT,
  555.                TOP_ItalicAngle);
  556.     cff_put_int_if_ne(pcw, info.UnderlinePosition,
  557.               UnderlinePosition_DEFAULT, TOP_UnderlinePosition);
  558.     cff_put_int_if_ne(pcw, info.UnderlineThickness,
  559.               UnderlineThickness_DEFAULT, TOP_UnderlineThickness);
  560.     cff_put_int_if_ne(pcw, pbfont->PaintType, PaintType_DEFAULT,
  561.               TOP_PaintType);
  562.     }
  563.     {
  564.     static const gs_matrix fm_default = {
  565.         constant_matrix_body(0.001, 0, 0, 0.001, 0, 0)
  566.     };
  567.  
  568.     if (pbfont->FontMatrix.xx != fm_default.xx ||
  569.         pbfont->FontMatrix.xy != 0 || pbfont->FontMatrix.yx != 0 ||
  570.         pbfont->FontMatrix.yy != fm_default.yy ||
  571.         pbfont->FontMatrix.tx != 0 || pbfont->FontMatrix.ty != 0
  572.         ) {
  573.         cff_put_real(pcw, pbfont->FontMatrix.xx);
  574.         cff_put_real(pcw, pbfont->FontMatrix.xy);
  575.         cff_put_real(pcw, pbfont->FontMatrix.yx);
  576.         cff_put_real(pcw, pbfont->FontMatrix.yy);
  577.         cff_put_real(pcw, pbfont->FontMatrix.tx);
  578.         cff_put_real(pcw, pbfont->FontMatrix.ty);
  579.         cff_put_op(pcw, TOP_FontMatrix);
  580.     }
  581.     }
  582.     cff_put_real_if_ne(pcw, pbfont->StrokeWidth, StrokeWidth_DEFAULT,
  583.                TOP_StrokeWidth);
  584. }
  585.  
  586. /* Type 1 or Type 2 font */
  587. private void
  588. cff_write_Top_font(cff_writer_t *pcw, uint Encoding_offset,
  589.            uint charset_offset, uint CharStrings_offset,
  590.            uint Private_offset, uint Private_size)
  591. {
  592.     gs_font_base *pbfont = (gs_font_base *)pcw->pfont;
  593.  
  594.     cff_write_Top_common(pcw, pbfont, true);
  595.     cff_put_int(pcw, Private_size);
  596.     cff_put_int_value(pcw, Private_offset, TOP_Private);
  597.     cff_put_int_value(pcw, CharStrings_offset, TOP_CharStrings);
  598.     cff_put_int_if_ne(pcw, charset_offset, charset_DEFAULT, TOP_charset);
  599.     cff_put_int_if_ne(pcw, Encoding_offset, Encoding_DEFAULT, TOP_Encoding);
  600.     {
  601.     int type = (pcw->options & WRITE_TYPE2_CHARSTRINGS ? 2 :
  602.             pbfont->FontType == ft_encrypted2 ? 2 : 1);
  603.  
  604.     cff_put_int_if_ne(pcw, type, CharstringType_DEFAULT,
  605.               TOP_CharstringType);
  606.     }
  607. }
  608.  
  609. /* CIDFontType 0 CIDFont */
  610. private void
  611. cff_write_ROS(cff_writer_t *pcw, const gs_cid_system_info_t *pcidsi)
  612. {
  613.     cff_put_string(pcw, pcidsi->Registry.data, pcidsi->Registry.size);
  614.     cff_put_string(pcw, pcidsi->Ordering.data, pcidsi->Ordering.size);
  615.     cff_put_int_value(pcw, pcidsi->Supplement, TOP_ROS);
  616. }
  617. private void
  618. cff_write_Top_cidfont(cff_writer_t *pcw, uint charset_offset,
  619.               uint CharStrings_offset, uint FDSelect_offset,
  620.               uint Font_offset)
  621. {
  622.     gs_font_base *pbfont = (gs_font_base *)pcw->pfont;
  623.     gs_font_cid0 *pfont = (gs_font_cid0 *)pbfont;
  624.  
  625.     cff_write_ROS(pcw, &pfont->cidata.common.CIDSystemInfo);
  626.     cff_write_Top_common(pcw, pbfont, true);
  627.     cff_put_int_if_ne(pcw, charset_offset, charset_DEFAULT, TOP_charset);
  628.     cff_put_int_value(pcw, CharStrings_offset, TOP_CharStrings);
  629.     /*
  630.      * CIDFontVersion and CIDFontRevision aren't used consistently,
  631.      * so we don't currently write them.  CIDFontType is always 0.
  632.      */
  633.     cff_put_int_if_ne(pcw, pfont->cidata.common.CIDCount, CIDCount_DEFAULT,
  634.               TOP_CIDCount);
  635.     /* We don't use UIDBase. */
  636.     cff_put_int_value(pcw, Font_offset, TOP_FDArray);
  637.     cff_put_int_value(pcw, FDSelect_offset, TOP_FDSelect);
  638. }
  639.  
  640. /* FDArray Index for CIDFont (offsets only) */
  641. private void
  642. cff_write_FDArray_offsets(cff_writer_t *pcw, uint *FDArray_offsets,
  643.               int num_fonts)
  644. {
  645.     int j;
  646.  
  647.     cff_put_Index_header(pcw, num_fonts,
  648.              FDArray_offsets[num_fonts] - FDArray_offsets[0]);
  649.     for (j = 1; j <= num_fonts; ++j)
  650.     put_offset(pcw, FDArray_offsets[j] - FDArray_offsets[0] + 1);
  651. }
  652.  
  653. /* FDArray entry for CIDFont */
  654. private void
  655. cff_write_Top_fdarray(cff_writer_t *pcw, gs_font_base *pbfont,
  656.               uint Private_offset, uint Private_size)
  657. {
  658.     const gs_font_name *pfname = &pbfont->font_name;
  659.  
  660.     cff_write_Top_common(pcw, pbfont, false);
  661.     cff_put_int(pcw, Private_size);
  662.     cff_put_int_value(pcw, Private_offset, TOP_Private);
  663.     if (pfname->size == 0)
  664.     pfname = &pbfont->key_name;
  665.     if (pfname->size) {
  666.     cff_put_string(pcw, pfname->chars, pfname->size);
  667.     cff_put_op(pcw, TOP_FontName);
  668.     }
  669. }
  670.  
  671. /* ------ Private Dict ------ */
  672.  
  673. /* Defaults are noted in comments. */
  674. typedef enum {
  675.     PRIVATE_BlueValues = 6,    /* (deltarray) */
  676.     PRIVATE_OtherBlues = 7,    /* (deltarray) */
  677.     PRIVATE_FamilyBlues = 8,    /* (deltarray) */
  678.     PRIVATE_FamilyOtherBlues = 9, /* (deltarray) */
  679.     PRIVATE_StdHW = 10,
  680.     PRIVATE_StdVW = 11,
  681.     PRIVATE_Subrs = 19,        /* (offset, relative to Private Dict) */
  682.     PRIVATE_defaultWidthX = 20,
  683. #define defaultWidthX_DEFAULT fixed_0
  684.     PRIVATE_nominalWidthX = 21,
  685. #define nominalWidthX_DEFAULT fixed_0
  686.     PRIVATE_BlueScale = 41,
  687. #define BlueScale_DEFAULT 0.039625
  688.     PRIVATE_BlueShift = 42,
  689. #define BlueShift_DEFAULT 7
  690.     PRIVATE_BlueFuzz = 43,
  691. #define BlueFuzz_DEFAULT 1
  692.     PRIVATE_StemSnapH = 44,    /* (deltarray) */
  693.     PRIVATE_StemSnapV = 45,    /* (deltarray) */
  694.     PRIVATE_ForceBold = 46,
  695. #define ForceBold_DEFAULT false
  696.     PRIVATE_ForceBoldThreshold = 47,
  697. #define ForceBoldThreshold_DEFAULT 0
  698.     PRIVATE_lenIV = 48,
  699. #define lenIV_DEFAULT (-1)
  700.     PRIVATE_LanguageGroup = 49,
  701. #define LanguageGroup_DEFAULT 0
  702.     PRIVATE_ExpansionFactor = 50,
  703. #define ExpansionFactor_DEFAULT 0.06
  704.     PRIVATE_initialRandomSeed = 51
  705. #define initialRandomSeed_DEFAULT 0
  706. } Private_op;
  707.  
  708. private void
  709. cff_write_Private(cff_writer_t *pcw, uint Subrs_offset,
  710.           const gs_font_type1 *pfont)
  711. {
  712. #define PUT_FLOAT_TABLE(member, op)\
  713.     cff_put_real_deltarray(pcw, pfont->data.member.values,\
  714.                pfont->data.member.count, op)
  715.                 
  716.     PUT_FLOAT_TABLE(BlueValues, PRIVATE_BlueValues);
  717.     PUT_FLOAT_TABLE(OtherBlues, PRIVATE_OtherBlues);
  718.     PUT_FLOAT_TABLE(FamilyBlues, PRIVATE_FamilyBlues);
  719.     PUT_FLOAT_TABLE(FamilyOtherBlues, PRIVATE_FamilyOtherBlues);
  720.     if (pfont->data.StdHW.count > 0)
  721.     cff_put_real_value(pcw, pfont->data.StdHW.values[0], PRIVATE_StdHW);
  722.     if (pfont->data.StdVW.count > 0)
  723.     cff_put_real_value(pcw, pfont->data.StdVW.values[0], PRIVATE_StdVW);
  724.     if (Subrs_offset)
  725.     cff_put_int_value(pcw, Subrs_offset, PRIVATE_Subrs);
  726.     if (pfont->FontType != ft_encrypted) {
  727.     if (pfont->data.defaultWidthX != defaultWidthX_DEFAULT)
  728.         cff_put_real_value(pcw, fixed2float(pfont->data.defaultWidthX),
  729.                    PRIVATE_defaultWidthX);
  730.     if (pfont->data.nominalWidthX != nominalWidthX_DEFAULT)
  731.         cff_put_real_value(pcw, fixed2float(pfont->data.nominalWidthX),
  732.                    PRIVATE_nominalWidthX);
  733.     cff_put_int_if_ne(pcw, pfont->data.initialRandomSeed,
  734.               initialRandomSeed_DEFAULT,
  735.               PRIVATE_initialRandomSeed);
  736.     }
  737.     cff_put_real_if_ne(pcw, pfont->data.BlueScale, BlueScale_DEFAULT,
  738.                PRIVATE_BlueScale);
  739.     cff_put_real_if_ne(pcw, pfont->data.BlueShift, BlueShift_DEFAULT,
  740.                PRIVATE_BlueShift);
  741.     cff_put_int_if_ne(pcw, pfont->data.BlueFuzz, BlueFuzz_DEFAULT,
  742.               PRIVATE_BlueFuzz);
  743.     PUT_FLOAT_TABLE(StemSnapH, PRIVATE_StemSnapH);
  744.     PUT_FLOAT_TABLE(StemSnapV, PRIVATE_StemSnapV);
  745.     if (pfont->data.ForceBold != ForceBold_DEFAULT)
  746.     cff_put_bool_value(pcw, pfont->data.ForceBold,
  747.                PRIVATE_ForceBold);
  748.     /* (ForceBoldThreshold) */
  749.     if (!(pcw->options & WRITE_TYPE2_NO_LENIV))
  750.     cff_put_int_if_ne(pcw, pfont->data.lenIV, lenIV_DEFAULT,
  751.               PRIVATE_lenIV);
  752.     cff_put_int_if_ne(pcw, pfont->data.LanguageGroup, LanguageGroup_DEFAULT,
  753.               PRIVATE_LanguageGroup);
  754.     cff_put_real_if_ne(pcw, pfont->data.ExpansionFactor,
  755.                ExpansionFactor_DEFAULT, PRIVATE_ExpansionFactor);
  756.     /* initialRandomSeed was handled above */
  757.  
  758. #undef PUT_FLOAT_TABLE
  759. }
  760.  
  761. /* ------ CharStrings Index ------ */
  762.  
  763. /* These are separate procedures only for readability. */
  764. private int
  765. cff_write_CharStrings_offsets(cff_writer_t *pcw, psf_glyph_enum_t *penum,
  766.                   uint *pcount)
  767. {
  768.     gs_font_base *pfont = pcw->pfont;
  769.     int offset;
  770.     gs_glyph glyph;
  771.     uint count;
  772.     gs_const_string str;
  773.     stream poss;
  774.     int code;
  775.  
  776.     psf_enumerate_glyphs_reset(penum);
  777.     for (glyph = gs_no_glyph, count = 0, offset = 1;
  778.      (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
  779.      ++count) {
  780.     gs_font_type1 *pfd;
  781.     int extra_lenIV;
  782.  
  783.     if (code == 0 &&
  784.         pcw->glyph_data(pfont, glyph, &str, &pfd) >= 0 &&
  785.         str.size >= (extra_lenIV = cff_extra_lenIV(pcw, pfd))
  786.         ) {
  787.         if (cff_convert_charstrings(pcw, (gs_font_base *)pfd)) {
  788.         swrite_position_only(&poss);
  789.         code = psf_convert_type1_to_type2(&poss, &str, pfd);
  790.         if (code < 0)
  791.             return code;
  792.         offset += stell(&poss);
  793.         } else
  794.         offset += str.size - extra_lenIV;
  795.     }
  796.     put_offset(pcw, offset);
  797.     }
  798.     *pcount = count;
  799.     return offset - 1;
  800. }
  801. private void
  802. cff_write_CharStrings(cff_writer_t *pcw, psf_glyph_enum_t *penum,
  803.               uint charstrings_count, uint charstrings_size)
  804. {
  805.     gs_font_base *pfont = pcw->pfont;
  806.     uint ignore_count;
  807.     gs_glyph glyph;
  808.     int code;
  809.  
  810.     cff_put_Index_header(pcw, charstrings_count, charstrings_size);
  811.     cff_write_CharStrings_offsets(pcw, penum, &ignore_count);
  812.     psf_enumerate_glyphs_reset(penum);
  813.     for (glyph = gs_no_glyph;
  814.      (code = psf_enumerate_glyphs_next(penum, &glyph)) != 1;
  815.      ) {
  816.     gs_const_string str;
  817.     gs_font_type1 *pfd;
  818.  
  819.     if (code == 0 &&
  820.         pcw->glyph_data(pfont, glyph, &str, &pfd) >= 0)
  821.         cff_put_CharString(pcw, str.data, str.size, pfd);
  822.     }
  823. }
  824.  
  825. /* ------ Subrs Index ------ */
  826.  
  827. /*
  828.  * Currently, we always write all the Subrs, even for subsets.
  829.  * We will fix this someday.
  830.  */
  831.  
  832. /* These are separate procedures only for readability. */
  833. private uint
  834. cff_write_Subrs_offsets(cff_writer_t *pcw, uint *pcount, gs_font_type1 *pfont)
  835. {
  836.     int extra_lenIV = cff_extra_lenIV(pcw, pfont);
  837.     int j, offset;
  838.     int code;
  839.     gs_const_string str;
  840.  
  841.     for (j = 0, offset = 1;
  842.      (code = (*pfont->data.procs.subr_data)(pfont, j, false, &str)) !=
  843.          gs_error_rangecheck;
  844.      ++j) {
  845.     if (code >= 0 && str.size >= extra_lenIV)
  846.         offset += str.size - extra_lenIV;
  847.     put_offset(pcw, offset);
  848.     }
  849.     *pcount = j;
  850.     return offset - 1;
  851. }
  852. private void
  853. cff_write_Subrs(cff_writer_t *pcw, uint subrs_count, uint subrs_size,
  854.         gs_font_type1 *pfont)
  855. {
  856.     int j;
  857.     uint ignore_count;
  858.     gs_const_string str;
  859.     int code;
  860.  
  861.     cff_put_Index_header(pcw, subrs_count, subrs_size);
  862.     cff_write_Subrs_offsets(pcw, &ignore_count, pfont);
  863.     for (j = 0;
  864.      (code = (*pfont->data.procs.subr_data)(pfont, j, false, &str)) !=
  865.          gs_error_rangecheck;
  866.      ++j) {
  867.     if (code >= 0)
  868.         cff_put_CharString(pcw, str.data, str.size, pfont);
  869.     }
  870. }
  871.  
  872. /* ------ Encoding/charset ------ */
  873.  
  874. private uint
  875. cff_Encoding_size(int num_encoded, int num_encoded_chars)
  876. {
  877.     return 2 + num_encoded +
  878.     (num_encoded_chars > num_encoded ?
  879.      1 + (num_encoded_chars - num_encoded) * 3 : 0);
  880. }
  881.  
  882. private int
  883. cff_write_Encoding(cff_writer_t *pcw, cff_glyph_subset_t *pgsub)
  884. {
  885.     stream *s = pcw->strm;
  886.     /* This procedure is only used for Type 1 / Type 2 fonts. */
  887.     gs_font_type1 *pfont = (gs_font_type1 *)pcw->pfont;
  888.     int num_enc = pgsub->num_encoded, num_enc_chars = pgsub->num_encoded_chars;
  889.     byte used[256], index[256], supplement[256];
  890.     int nsupp = 0;
  891.     int j;
  892.  
  893.     sputc(s, (num_enc_chars > num_enc ? 0x80 : 0));
  894.     memset(used, 0, num_enc);
  895.     if (num_enc == 256) {
  896.     /*
  897.      * The count of encoded characters is only a single byte, so we
  898.      * have to use a supplement for the last character.
  899.      */
  900.     /****** NYI ******/
  901.     }
  902.     sputc(s, num_enc);
  903.     for (j = 0; j < 256; ++j) {
  904.     gs_glyph glyph = pfont->procs.encode_char((gs_font *)pfont,
  905.                           (gs_char)j,
  906.                           GLYPH_SPACE_NAME);
  907.     int i;
  908.  
  909.     if (glyph == gs_no_glyph || glyph == pgsub->glyphs.notdef)
  910.         continue;
  911.     i = psf_sorted_glyphs_index_of(pgsub->glyphs.subset_data + 1,
  912.                        num_enc, glyph);
  913.     if (i < 0)
  914.         continue;        /* encoded but not in subset */
  915.     if (used[i])
  916.         supplement[nsupp++] = j;
  917.     else
  918.         index[i] = j, used[i] = 1;
  919.     }
  920. #ifdef DEBUG
  921.     if (nsupp != num_enc_chars - num_enc)
  922.     lprintf3("nsupp = %d, num_enc_chars = %d, num_enc = %d\n",
  923.          nsupp, num_enc_chars, num_enc);
  924.     for (j = 0; j < num_enc; ++j)
  925.     if (!used[j])
  926.         lprintf2("glyph %d = 0x%lx not used\n", j,
  927.              pgsub->glyphs.subset_data[j + 1]);
  928. #endif
  929.     put_bytes(s, index, num_enc);
  930.     if (nsupp) {
  931.     /* Write supplementary entries for multiply-encoded glyphs. */
  932.     sputc(s, nsupp);
  933.     for (j = 0; j < nsupp; ++j) {
  934.         byte chr = supplement[j];
  935.  
  936.         sputc(s, chr);
  937.         put_card16(pcw,
  938.         cff_glyph_sid(pcw,
  939.                   pfont->procs.encode_char((gs_font *)pfont,
  940.                                (gs_char)chr,
  941.                                GLYPH_SPACE_NAME)));
  942.     }
  943.     }
  944.     return 0;
  945. }
  946.  
  947. private int
  948. cff_write_charset(cff_writer_t *pcw, cff_glyph_subset_t *pgsub)
  949. {
  950.     int j;
  951.  
  952.     sputc(pcw->strm, 0);
  953.     for (j = 1; j < pgsub->glyphs.subset_size; ++j)
  954.     put_card16(pcw, cff_glyph_sid(pcw, pgsub->glyphs.subset_data[j]));
  955.     return 0;
  956. }
  957. private int
  958. cff_write_cidset(cff_writer_t *pcw, psf_glyph_enum_t *penum)
  959. {
  960.     gs_glyph glyph;
  961.     int code;
  962.  
  963.     sputc(pcw->strm, 0);
  964.     psf_enumerate_glyphs_reset(penum);
  965.     while ((code = psf_enumerate_glyphs_next(penum, &glyph)) == 0)
  966.     put_card16(pcw, (uint)(glyph - gs_min_cid_glyph));
  967.     return min(code, 0);
  968. }
  969.  
  970. /* ------ FDSelect ------ */
  971.  
  972. /* Determine the size of FDSelect. */
  973. private uint
  974. cff_FDSelect_size(cff_writer_t *pcw)
  975. {
  976.     gs_font_cid0 *const pfont = (gs_font_cid0 *)pcw->pfont;
  977.     gs_font_base *const pbfont = (gs_font_base *)pfont;
  978.     int cid_count = pfont->cidata.common.CIDCount;
  979.     int i, prev, num_ranges;
  980.  
  981.     /* Determine whether format 0 or 3 is more efficient. */
  982.     for (i = 0, prev = -1, num_ranges = 0; i < cid_count; ++i) {
  983.     int font_index;
  984.     int code = pfont->cidata.glyph_data(pbfont,
  985.                         (gs_glyph)(i + gs_min_cid_glyph),
  986.                         NULL, &font_index);
  987.  
  988.     if (code >= 0) {
  989.         if (font_index != prev)
  990.         ++num_ranges, prev = font_index;
  991.     }
  992.     }
  993.     return min(1 + cid_count, 5 + num_ranges * 3);
  994. }
  995.  
  996. /* Write FDSelect.  size is the value returned by cff_FDSelect_size. */
  997. private int
  998. cff_write_FDSelect(cff_writer_t *pcw, uint size)
  999. {
  1000.     stream *s = pcw->strm;
  1001.     gs_font_cid0 *const pfont = (gs_font_cid0 *)pcw->pfont;
  1002.     gs_font_base *const pbfont = (gs_font_base *)pfont;
  1003.     int cid_count = pfont->cidata.common.CIDCount;
  1004.     int i, prev;
  1005.  
  1006.     if (size < 1 + cid_count) {
  1007.     /* Use format 3 (ranges). */
  1008.     spputc(s, 3);
  1009.     put_card16(pcw, (size - 5) / 3);
  1010.     for (i = 0, prev = -1; i < cid_count; ++i) {
  1011.         int font_index;
  1012.         int code = pfont->cidata.glyph_data(pbfont,
  1013.                     (gs_glyph)(i + gs_min_cid_glyph),
  1014.                         NULL, &font_index);
  1015.  
  1016.         if (code >= 0) {
  1017.         if (font_index != prev) {
  1018.             put_card16(pcw, i);
  1019.             sputc(s, (byte)font_index);
  1020.             prev = font_index;
  1021.         }
  1022.         }
  1023.     }
  1024.     put_card16(pcw, cid_count);
  1025.     } else {
  1026.     /* Use format 0 (linear table). */
  1027.     spputc(s, 0);
  1028.     for (i = 0; i < cid_count; ++i) {
  1029.         int font_index = 0;    /* in case of error */
  1030.  
  1031.         pfont->cidata.glyph_data(pbfont,
  1032.                      (gs_glyph)(i + gs_min_cid_glyph),
  1033.                      NULL, &font_index);
  1034.         sputc(s, (byte)font_index);
  1035.     }
  1036.     }
  1037.     return 0;
  1038. }
  1039.  
  1040. /* ------ Main procedure ------ */
  1041.  
  1042. /* Write the CFF definition of a Type 1 or Type 2 font. */
  1043. int
  1044. psf_write_type2_font(stream *s, gs_font_type1 *pfont, int options,
  1045.               gs_glyph *subset_glyphs, uint subset_size,
  1046.               const gs_const_string *alt_font_name)
  1047. {
  1048.     gs_font_base *const pbfont = (gs_font_base *)pfont;
  1049.     cff_writer_t writer;
  1050.     cff_glyph_subset_t subset;
  1051.     cff_string_item_t std_string_items[500]; /* 391 entries used */
  1052.     /****** HOW TO DETERMINE THE SIZE OF STRINGS? ******/
  1053.     cff_string_item_t string_items[500 /* character names */ +
  1054.                    40 /* misc. values */];
  1055.     gs_const_string font_name;
  1056.     stream poss;
  1057.     uint charstrings_count, charstrings_size;
  1058.     uint subrs_count, subrs_size;
  1059.     uint encoding_size, charset_size;
  1060.     /*
  1061.      * Set the offsets and sizes to the largest reasonable values
  1062.      * (see below).
  1063.      */
  1064.     uint
  1065.     Top_size = 0xffff,
  1066.     Encoding_offset = 0xffff,
  1067.     charset_offset = 0xffff,
  1068.     CharStrings_offset = 0xffff,
  1069.     Private_offset = 0xffff,
  1070.     Private_size = 0xffff,
  1071.     Subrs_offset = 0xffff,
  1072.     End_offset = 0xffff;
  1073.     int j;
  1074.     psf_glyph_enum_t genum;
  1075.     gs_glyph glyph;
  1076.     long start_pos;
  1077.     uint offset;
  1078.     int code =
  1079.     psf_get_type1_glyphs(&subset.glyphs, pfont, subset_glyphs,
  1080.                   subset_size);
  1081.  
  1082.     if (code < 0)
  1083.     return code;
  1084.     if (subset.glyphs.notdef == gs_no_glyph)
  1085.     return_error(gs_error_rangecheck); /* notdef is required */
  1086.  
  1087.     /* If we're writing Type 2 CharStrings, don't encrypt them. */
  1088.     if (options & WRITE_TYPE2_CHARSTRINGS) {
  1089.     options |= WRITE_TYPE2_NO_LENIV;
  1090.     if (pfont->FontType != ft_encrypted2)
  1091.         pfont->data.defaultWidthX = pfont->data.nominalWidthX = 0;
  1092.     }
  1093.     writer.options = options;
  1094.     swrite_position_only(&poss);
  1095.     writer.strm = &poss;
  1096.     writer.pfont = pbfont;
  1097.     writer.glyph_data = psf_type1_glyph_data;
  1098.     writer.offset_size = 1;    /* arbitrary */
  1099.     writer.start_pos = stell(s);
  1100.  
  1101.     /* Initialize the enumeration of the glyphs. */
  1102.     psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
  1103.                 subset.glyphs.subset_glyphs,
  1104.                 (subset.glyphs.subset_glyphs ?
  1105.                  subset.glyphs.subset_size : 0),
  1106.                 GLYPH_SPACE_NAME);
  1107.  
  1108.     /* Shuffle the glyphs into the order .notdef, encoded, unencoded. */
  1109.     {
  1110.     gs_glyph encoded[256];
  1111.     int num_enc, num_enc_chars;
  1112.  
  1113.     /* Get the list of encoded glyphs. */
  1114.     for (j = 0, num_enc_chars = 0; j < 256; ++j) {
  1115.         glyph = pfont->procs.encode_char((gs_font *)pfont, (gs_char)j,
  1116.                          GLYPH_SPACE_NAME);
  1117.         if (glyph != gs_no_glyph && glyph != subset.glyphs.notdef &&
  1118.         (subset.glyphs.subset_glyphs == 0 ||
  1119.          psf_sorted_glyphs_include(subset.glyphs.subset_data,
  1120.                         subset.glyphs.subset_size, glyph)))
  1121.         encoded[num_enc_chars++] = glyph;
  1122.     }
  1123.     subset.num_encoded_chars = num_enc_chars;
  1124.     subset.num_encoded = num_enc =
  1125.         psf_sort_glyphs(encoded, num_enc_chars);
  1126.  
  1127.     /* Get the complete list of glyphs if we don't have it already. */
  1128.     if (!subset.glyphs.subset_glyphs) {
  1129.         int num_glyphs = 0;
  1130.  
  1131.         psf_enumerate_glyphs_reset(&genum);
  1132.         while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
  1133.         if (code == 0) {
  1134.             if (num_glyphs == countof(subset.glyphs.subset_data))
  1135.             return_error(gs_error_limitcheck);
  1136.             subset.glyphs.subset_data[num_glyphs++] = glyph;
  1137.         }
  1138.         subset.glyphs.subset_size =
  1139.         psf_sort_glyphs(subset.glyphs.subset_data, num_glyphs);
  1140.         subset.glyphs.subset_glyphs = subset.glyphs.subset_data;
  1141.     }
  1142.  
  1143.     /* Move the unencoded glyphs to the top of the list. */
  1144.     /*
  1145.      * We could do this in time N rather than N log N with a two-finger
  1146.      * algorithm, but it doesn't seem worth the trouble right now.
  1147.      */
  1148.     {
  1149.         int from = subset.glyphs.subset_size;
  1150.         int to = from;
  1151.  
  1152.         while (from > 0) {
  1153.         glyph = subset.glyphs.subset_data[--from];
  1154.         if (glyph != subset.glyphs.notdef &&
  1155.             !psf_sorted_glyphs_include(encoded, num_enc, glyph))
  1156.             subset.glyphs.subset_data[--to] = glyph;
  1157.         }
  1158. #ifdef DEBUG
  1159.         if (to != num_enc + 1)
  1160.         lprintf2("to = %d, num_enc + 1 = %d\n", to, num_enc + 1);
  1161. #endif
  1162.     }
  1163.  
  1164.     /* Move .notdef and the encoded glyphs to the bottom of the list. */
  1165.     subset.glyphs.subset_data[0] = subset.glyphs.notdef;
  1166.     memcpy(subset.glyphs.subset_data + 1, encoded,
  1167.            sizeof(encoded[0]) * num_enc);
  1168.     }
  1169.  
  1170.     /* Set the font name. */
  1171.     if (alt_font_name)
  1172.     font_name = *alt_font_name;
  1173.     else
  1174.     font_name.data = pfont->font_name.chars,
  1175.         font_name.size = pfont->font_name.size;
  1176.  
  1177.     /* Initialize the string tables. */
  1178.     cff_string_table_init(&writer.std_strings, std_string_items,
  1179.               countof(std_string_items));
  1180.     for (j = 0; (glyph = pfont->procs.callbacks.known_encode((gs_char)j,
  1181.                 ENCODING_INDEX_CFFSTRINGS)) != gs_no_glyph;
  1182.      ++j) {
  1183.     uint size;
  1184.     const byte *str = (const byte *)
  1185.         pfont->procs.callbacks.glyph_name(glyph, &size);
  1186.     int ignore;
  1187.  
  1188.     cff_string_index(&writer.std_strings, str, size, true, &ignore);
  1189.     }
  1190.     cff_string_table_init(&writer.strings, string_items,
  1191.               countof(string_items));
  1192.  
  1193.     /* Enter miscellaneous strings in the string table. */
  1194.     cff_write_Top_font(&writer, 0, 0, 0, 0, 0);
  1195.  
  1196.     /* Enter the glyph names in the string table. */
  1197.     /* (Note that we have changed the glyph list.) */
  1198.     psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont,
  1199.                    subset.glyphs.subset_data,
  1200.                    subset.glyphs.subset_size,
  1201.                    GLYPH_SPACE_NAME);
  1202.     while ((code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1)
  1203.     if (code == 0) {
  1204.         code = cff_glyph_sid(&writer, glyph);
  1205.         if (code < 0)
  1206.         return code;
  1207.     }
  1208.  
  1209.     /*
  1210.      * The CFF specification says that the Encoding, charset, CharStrings,
  1211.      * Private, and Local Subr sections may be in any order.  To minimize
  1212.      * the risk of incompatibility with Adobe software, we produce them in
  1213.      * the order just mentioned.
  1214.      */
  1215.  
  1216.     /*
  1217.      * Compute the size of the Encoding.  For simplicity, we currently
  1218.      * always store the Encoding explicitly.  Note that because CFF stores
  1219.      * the Encoding in an "inverted" form, we need to count the number of
  1220.      * glyphs that occur at more than one place in the Encoding.
  1221.      */
  1222.     encoding_size = cff_Encoding_size(subset.num_encoded,
  1223.                       subset.num_encoded_chars);
  1224.  
  1225.     /*
  1226.      * Compute the size of the charset.  For simplicity, we currently
  1227.      * always store the charset explicitly.
  1228.      */
  1229.     charset_size = 1 + (subset.glyphs.subset_size - 1) * 2;
  1230.  
  1231.     /* Compute the size of the CharStrings Index. */
  1232.     charstrings_size =
  1233.     cff_write_CharStrings_offsets(&writer, &genum, &charstrings_count);
  1234.  
  1235.     /* Compute the size of the (local) Subrs Index. */
  1236. #ifdef SKIP_EMPTY_SUBRS
  1237.     subrs_size =
  1238.     (cff_convert_charstrings(&writer, pbfont) ? 0 :
  1239.      cff_write_Subrs_offsets(&writer, &subrs_count, pfont));
  1240. #else
  1241.     if (cff_convert_charstrings(&writer, pbfont))
  1242.     subrs_count = 0;    /* we expand all Subrs */
  1243.     subrs_size = cff_write_Subrs_offsets(&writer, &subrs_count, pfont);
  1244. #endif
  1245.  
  1246.     /*
  1247.      * The offsets of the Private Dict and the CharStrings Index
  1248.      * depend on the size of the Top Dict; the offset of the Subrs also
  1249.      * depends on the size of the Private Dict.  However, the size of the
  1250.      * Top Dict depends on the offsets of the CharStrings Index, the
  1251.      * charset, and the Encoding, and on the offset and size of the Private
  1252.      * Dict, because of the variable-length encoding of the offsets and
  1253.      * size; for the same reason, the size of the Private Dict depends on
  1254.      * the offset of the Subrs.  Fortunately, the relationship between the
  1255.      * value of an offset or size and the size of its encoding is monotonic.
  1256.      * Therefore, we start by assuming the largest reasonable value for all
  1257.      * the sizes and iterate until everything converges.
  1258.      */
  1259.  iter:
  1260.     swrite_position_only(&poss);
  1261.     writer.strm = &poss;
  1262.  
  1263.     /* Compute the offsets. */
  1264.     Encoding_offset = 4 + cff_Index_size(1, font_name.size) +
  1265.     cff_Index_size(1, Top_size) +
  1266.     cff_Index_size(writer.strings.count, writer.strings.total) +
  1267.     cff_Index_size(0, 0);
  1268.     charset_offset = Encoding_offset + encoding_size;
  1269.     CharStrings_offset = charset_offset + charset_size;
  1270.     Private_offset = CharStrings_offset +
  1271.     cff_Index_size(charstrings_count, charstrings_size);
  1272.     Subrs_offset = Private_size;  /* relative to Private Dict */
  1273.  
  1274.  write:
  1275.     start_pos = stell(writer.strm);
  1276.     /* Write the header. */
  1277.     put_bytes(writer.strm, (const byte *)"\001\000\004\002", 4);
  1278.  
  1279.     /* Write the names Index. */
  1280.     cff_put_Index_header(&writer, 1, font_name.size);
  1281.     put_offset(&writer, font_name.size + 1);
  1282.     put_bytes(writer.strm, font_name.data, font_name.size);
  1283.  
  1284.     /* Write the Top Index. */
  1285.     cff_put_Index_header(&writer, 1, Top_size);
  1286.     put_offset(&writer, Top_size + 1);
  1287.     offset = stell(writer.strm) - start_pos;
  1288.     cff_write_Top_font(&writer, Encoding_offset, charset_offset,
  1289.                CharStrings_offset,
  1290.                Private_offset, Private_size);
  1291.     Top_size = stell(writer.strm) - start_pos - offset;
  1292.  
  1293.     /* Write the strings Index. */
  1294.     cff_put_Index(&writer, &writer.strings);
  1295.  
  1296.     /* Write the (empty) gsubrs Index. */
  1297.     cff_put_Index_header(&writer, 0, 0);
  1298.  
  1299.     /* Write the Encoding. */
  1300.     cff_write_Encoding(&writer, &subset);
  1301.  
  1302.     /* Write the charset. */
  1303.     cff_write_charset(&writer, &subset);
  1304.  
  1305.     /* Write the CharStrings Index, checking the offset. */
  1306.     offset = stell(writer.strm) - start_pos;
  1307.     if (offset > CharStrings_offset)
  1308.     return_error(gs_error_rangecheck);
  1309.     CharStrings_offset = offset;
  1310.     cff_write_CharStrings(&writer, &genum, charstrings_count,
  1311.               charstrings_size);
  1312.  
  1313.     /* Write the Private Dict, checking the offset. */
  1314.     offset = stell(writer.strm) - start_pos;
  1315.     if (offset > Private_offset)
  1316.     return_error(gs_error_rangecheck);
  1317.     Private_offset = offset;
  1318.     cff_write_Private(&writer, (subrs_size == 0 ? 0 : Subrs_offset), pfont);
  1319.     Private_size = stell(writer.strm) - start_pos - offset;
  1320.  
  1321.     /* Write the Subrs Index, checking the offset. */
  1322.     offset = stell(writer.strm) - (start_pos + Private_offset);
  1323.     if (offset > Subrs_offset)
  1324.     return_error(gs_error_rangecheck);
  1325.     Subrs_offset = offset;
  1326.     if (cff_convert_charstrings(&writer, pbfont))
  1327.     cff_put_Index_header(&writer, 0, 0);
  1328.     else if (subrs_size != 0)
  1329.     cff_write_Subrs(&writer, subrs_count, subrs_size, pfont);
  1330.  
  1331.     /* Check the final offset. */
  1332.     offset = stell(writer.strm) - start_pos;
  1333.     if (offset > End_offset)
  1334.     return_error(gs_error_rangecheck);
  1335.     if (offset == End_offset) {
  1336.     /* The iteration has converged.  Write the result. */
  1337.     if (writer.strm == &poss) {
  1338.         writer.strm = s;
  1339.         goto write;
  1340.     }
  1341.     } else {
  1342.     /* No convergence yet. */
  1343.     End_offset = offset;
  1344.     goto iter;
  1345.     }
  1346.  
  1347.     /* All done. */
  1348.     return 0;
  1349. }
  1350.  
  1351. /* Write the CFF definition of a CIDFontType 0 font (CIDFont). */
  1352. private int
  1353. cid0_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_const_string *pstr,
  1354.         gs_font_type1 **ppfont)
  1355. {
  1356.     gs_font_cid0 *const pfont = (gs_font_cid0 *)pbfont;
  1357.     int font_index;
  1358.     int code = pfont->cidata.glyph_data(pbfont, glyph, pstr, &font_index);
  1359.  
  1360.     if (code >= 0)
  1361.     *ppfont = pfont->cidata.FDArray[font_index];
  1362.     return code;
  1363. }
  1364. #ifdef DEBUG
  1365. private int
  1366. offset_error(const char *msg)
  1367. {
  1368.     if_debug1('l', "[l]%s offset error\n", msg);
  1369.     return gs_error_rangecheck;
  1370. }
  1371. #else
  1372. #  define offset_error(msg) gs_error_rangecheck
  1373. #endif
  1374. int
  1375. psf_write_cid0_font(stream *s, gs_font_cid0 *pfont, int options,
  1376.             const byte *subset_cids, uint subset_size,
  1377.             const gs_const_string *alt_font_name)
  1378. {
  1379.     /*
  1380.      * CIDFontType 0 fonts differ from ordinary Type 1 / Type 2 fonts
  1381.      * as follows:
  1382.      *   The TOP Dict starts with a ROS operator.
  1383.      *   The TOP Dict must include FDArray and FDSelect operators.
  1384.      *   The TOP Dict may include CIDFontVersion, CIDFontRevision,
  1385.      *     CIDFontType, CIDCount, and UIDBase operators.
  1386.      *   The TOP Dict must not include an Encoding operator.
  1387.      *   The charset is defined in terms of CIDs rather than SIDs.
  1388.      *   FDArray references a Font Index in which each element is a Dict
  1389.      *     defining a font without charset, Encoding, or CharStrings.
  1390.      *   FDSelect references a structure mapping CIDs to font numbers.
  1391.      */
  1392.     gs_font_base *const pbfont = (gs_font_base *)pfont;
  1393.     cff_writer_t writer;
  1394.     cff_string_item_t std_string_items[500]; /* 391 entries used */
  1395.     /****** HOW TO DETERMINE THE SIZE OF STRINGS? ******/
  1396.     cff_string_item_t string_items[500 /* character names */ +
  1397.                    40 /* misc. values */];
  1398.     gs_const_string font_name;
  1399.     stream poss;
  1400.     uint charstrings_count, charstrings_size;
  1401.     uint charset_size, fdselect_size;
  1402.     uint subrs_count[256], subrs_size[256];
  1403.     /*
  1404.      * Set the offsets and sizes to the largest reasonable values
  1405.      * (see below).
  1406.      */
  1407.     uint
  1408.     Top_size = 0x7fffff,
  1409.     charset_offset = 0x7fffff,
  1410.     FDSelect_offset = 0x7fffff,
  1411.     CharStrings_offset = 0x7fffff,
  1412.     Font_offset = 0x7fffff,
  1413.     FDArray_offsets[257],
  1414.     Private_offsets[257],
  1415.     Subrs_offsets[257],
  1416.     End_offset = 0x7fffff;
  1417.     int j;
  1418.     psf_glyph_enum_t genum;
  1419.     long start_pos;
  1420.     uint offset;
  1421.     int num_fonts = pfont->cidata.FDArray_size;
  1422.     int code;
  1423.  
  1424.  
  1425.     /* Initialize the enumeration of the glyphs. */
  1426.     psf_enumerate_cids_begin(&genum, (gs_font *)pfont, subset_cids,
  1427.                  subset_size);
  1428.  
  1429.     /* Check that the font can be written. */
  1430.     code = psf_check_outline_glyphs((gs_font_base *)pfont, &genum,
  1431.                     cid0_glyph_data);
  1432.     if (code < 0)
  1433.     return code;
  1434.  
  1435.     writer.options = options;
  1436.     swrite_position_only(&poss);
  1437.     writer.strm = &poss;
  1438.     writer.pfont = pbfont;
  1439.     writer.glyph_data = cid0_glyph_data;
  1440.     writer.offset_size = 1;    /* arbitrary */
  1441.     writer.start_pos = stell(s);
  1442.  
  1443.     /* Set the font name. */
  1444.     if (alt_font_name)
  1445.     font_name = *alt_font_name;
  1446.     else if (pfont->font_name.size)
  1447.     font_name.data = pfont->font_name.chars,
  1448.         font_name.size = pfont->font_name.size;
  1449.     else
  1450.     font_name.data = pfont->key_name.chars,
  1451.         font_name.size = pfont->key_name.size;
  1452.  
  1453.     /* Initialize the string tables. */
  1454.     cff_string_table_init(&writer.std_strings, std_string_items,
  1455.               countof(std_string_items));
  1456.     cff_string_table_init(&writer.strings, string_items,
  1457.               countof(string_items));
  1458.  
  1459.     /* Make all entries in the string table. */
  1460.     cff_write_ROS(&writer, &pfont->cidata.common.CIDSystemInfo);
  1461.     for (j = 0; j < num_fonts; ++j) {
  1462.     gs_font_type1 *pfd = pfont->cidata.FDArray[j];
  1463.  
  1464.     cff_write_Top_fdarray(&writer, (gs_font_base *)pfd, 0, 0);
  1465.     }
  1466.  
  1467.     /*
  1468.      * The CFF specification says that sections after the initial Indexes
  1469.      * may be in any order.  To minimize the risk of incompatibility with
  1470.      * Adobe software, we produce them in the order illustrated in the
  1471.      * specification.
  1472.      */
  1473.  
  1474.     /* Initialize the offset arrays. */
  1475.     for (j = 0; j <= num_fonts; ++j)
  1476.     FDArray_offsets[j] = Private_offsets[j] = Subrs_offsets[j] =
  1477.         0x7effffff / num_fonts * j + 0x1000000;
  1478.  
  1479.     /*
  1480.      * Compute the size of the charset.  For simplicity, we currently
  1481.      * always store the charset explicitly.
  1482.      */
  1483.     swrite_position_only(&poss);
  1484.     cff_write_cidset(&writer, &genum);
  1485.     charset_size = stell(&poss);
  1486.  
  1487.     /* Compute the size of the FDSelect strucure. */
  1488.     fdselect_size = cff_FDSelect_size(&writer);
  1489.  
  1490.     /* Compute the size of the CharStrings Index. */
  1491.     charstrings_size =
  1492.     cff_write_CharStrings_offsets(&writer, &genum, &charstrings_count);
  1493.  
  1494.     /* Compute the size of the (local) Subrs Indexes. */
  1495.     for (j = 0; j < num_fonts; ++j) {
  1496.     gs_font_type1 *pfd = pfont->cidata.FDArray[j];
  1497.  
  1498. #ifdef SKIP_EMPTY_SUBRS
  1499.     subrs_size[j] =
  1500.         (cff_convert_charstrings(&writer, (gs_font_base *)pfd) ? 0 :
  1501.          cff_write_Subrs_offsets(&writer, &subrs_count[j], pfd));
  1502. #else
  1503.     if (cff_convert_charstrings(&writer, (gs_font_base *)pfd))
  1504.         subrs_count[j] = 0;  /* we expand all Subrs */
  1505.     subrs_size[j] = cff_write_Subrs_offsets(&writer, &subrs_count[j], pfd);
  1506. #endif
  1507.     }
  1508.  
  1509.     /*
  1510.      * The offsets of the Private Dict and the CharStrings Index
  1511.      * depend on the size of the Top Dict; the offset of the Subrs also
  1512.      * depends on the size of the Private Dict.  However, the size of the
  1513.      * Top Dict depends on the offsets of the CharStrings Index and the
  1514.      * charset, and on the offset and size of the Private Dict,
  1515.      * because of the variable-length encoding of the offsets and
  1516.      * size; for the same reason, the size of the Private Dict depends on
  1517.      * the offset of the Subrs.  Fortunately, the relationship between the
  1518.      * value of an offset or size and the size of its encoding is monotonic.
  1519.      * Therefore, we start by assuming the largest reasonable value for all
  1520.      * the sizes and iterate until everything converges.
  1521.      */
  1522.  iter:
  1523.     swrite_position_only(&poss);
  1524.     writer.strm = &poss;
  1525.  
  1526.     /* Compute the offsets. */
  1527.     charset_offset = 4 + cff_Index_size(1, font_name.size) +
  1528.     cff_Index_size(1, Top_size) +
  1529.     cff_Index_size(writer.strings.count, writer.strings.total) +
  1530.     cff_Index_size(0, 0);
  1531.     FDSelect_offset = charset_offset + charset_size;
  1532.     CharStrings_offset = FDSelect_offset + fdselect_size;
  1533.     if_debug3('l', "[l]charset at %u, FDSelect at %u, CharStrings at %u\n",
  1534.           charset_offset, FDSelect_offset, CharStrings_offset);
  1535.  
  1536.  write:
  1537.     start_pos = stell(writer.strm);
  1538.     if_debug1('l', "[l]start_pos = %ld\n", start_pos);
  1539.     writer.offset_size = (End_offset > 0x7fff ? 3 : 2);
  1540.     /* Write the header. */
  1541.     put_bytes(writer.strm, (const byte *)"\001\000\004", 3);
  1542.     sputc(writer.strm, writer.offset_size);
  1543.  
  1544.     /* Write the names Index. */
  1545.     cff_put_Index_header(&writer, 1, font_name.size);
  1546.     put_offset(&writer, font_name.size + 1);
  1547.     put_bytes(writer.strm, font_name.data, font_name.size);
  1548.  
  1549.     /* Write the Top Index. */
  1550.     cff_put_Index_header(&writer, 1, Top_size);
  1551.     put_offset(&writer, Top_size + 1);
  1552.     offset = stell(writer.strm) - start_pos;
  1553.     cff_write_Top_cidfont(&writer, charset_offset, CharStrings_offset,
  1554.               FDSelect_offset, Font_offset);
  1555.     Top_size = stell(writer.strm) - start_pos - offset;
  1556.     if_debug1('l', "[l]Top_size = %u\n", Top_size);
  1557.  
  1558.     /* Write the strings Index. */
  1559.     cff_put_Index(&writer, &writer.strings);
  1560.  
  1561.     /* Write the (empty) gsubrs Index. */
  1562.     cff_put_Index_header(&writer, 0, 0);
  1563.  
  1564.     /* Write the charset. */
  1565.     cff_write_cidset(&writer, &genum);
  1566.  
  1567.     /* Write the FDSelect structure, checking the offset. */
  1568.     offset = stell(writer.strm) - start_pos;
  1569.     if_debug2('l', "[l]FDSelect = %u => %u\n", FDSelect_offset, offset);
  1570.     if (offset > FDSelect_offset)
  1571.     return_error(offset_error("FDselect"));
  1572.     FDSelect_offset = offset;
  1573.     cff_write_FDSelect(&writer, fdselect_size);
  1574.  
  1575.     /* Write the CharStrings Index, checking the offset. */
  1576.     offset = stell(writer.strm) - start_pos;
  1577.     if_debug2('l', "[l]CharStrings = %u => %u\n", CharStrings_offset, offset);
  1578.     if (offset > CharStrings_offset)
  1579.     return_error(offset_error("CharStrings"));
  1580.     CharStrings_offset = offset;
  1581.     cff_write_CharStrings(&writer, &genum, charstrings_count,
  1582.               charstrings_size);
  1583.  
  1584.     /* Write the Font Dict Index. */
  1585.     offset = stell(writer.strm) - start_pos;
  1586.     if_debug2('l', "[l]Font = %u => %u\n", Font_offset, offset);
  1587.     if (offset > Font_offset)
  1588.     return_error(offset_error("Font"));
  1589.     Font_offset = offset;
  1590.     cff_write_FDArray_offsets(&writer, FDArray_offsets, num_fonts);
  1591.     offset = stell(writer.strm) - start_pos;
  1592.     if_debug2('l', "[l]FDArray[0] = %u => %u\n", FDArray_offsets[0], offset);
  1593.     if (offset > FDArray_offsets[0])
  1594.     return_error(offset_error("FDArray[0]"));
  1595.     FDArray_offsets[0] = offset;
  1596.     for (j = 0; j < num_fonts; ++j) {
  1597.     gs_font_type1 *pfd = pfont->cidata.FDArray[j];
  1598.  
  1599.     /* If we're writing Type 2 CharStrings, don't encrypt them. */
  1600.     if (options & WRITE_TYPE2_CHARSTRINGS) {
  1601.         options |= WRITE_TYPE2_NO_LENIV;
  1602.         if (pfd->FontType != ft_encrypted2)
  1603.         pfd->data.defaultWidthX = pfd->data.nominalWidthX = 0;
  1604.     }
  1605.     cff_write_Top_fdarray(&writer, (gs_font_base *)pfd, Private_offsets[j],
  1606.                   Private_offsets[j + 1] - Private_offsets[j]);
  1607.     offset = stell(writer.strm) - start_pos;
  1608.     if_debug3('l', "[l]FDArray[%d] = %u => %u\n", j + 1,
  1609.           FDArray_offsets[j + 1], offset);
  1610.     if (offset > FDArray_offsets[j + 1])
  1611.         return_error(offset_error("FDArray"));
  1612.     FDArray_offsets[j + 1] = offset;
  1613.     }
  1614.  
  1615.     /* Write the Private Dicts, checking the offset. */
  1616.     for (j = 0; ; ++j) {
  1617.     gs_font_type1 *pfd;
  1618.  
  1619.     offset = stell(writer.strm) - start_pos;
  1620.     if_debug3('l', "[l]Private[%d] = %u => %u\n",
  1621.           j, Private_offsets[j], offset);
  1622.     if (offset > Private_offsets[j])
  1623.         return_error(offset_error("Private"));
  1624.     Private_offsets[j] = offset;
  1625.     if (j == num_fonts)
  1626.         break;
  1627.     pfd = pfont->cidata.FDArray[j];
  1628.     cff_write_Private(&writer,
  1629.               (subrs_size[j] == 0 ? 0 : Subrs_offsets[j]), pfd);
  1630.     }
  1631.  
  1632.     /* Write the Subrs Indexes, checking the offsets. */
  1633.     for (j = 0; ; ++j) {
  1634.     gs_font_type1 *pfd;
  1635.  
  1636.     offset = stell(writer.strm) - (start_pos + Private_offsets[j]);
  1637.     if_debug3('l', "[l]Subrs[%d] = %u => %u\n",
  1638.           j, Subrs_offsets[j], offset);
  1639.     if (offset > Subrs_offsets[j])
  1640.         return_error(offset_error("Subrs"));
  1641.     Subrs_offsets[j] = offset;
  1642.     if (j == num_fonts)
  1643.         break;
  1644.     pfd = pfont->cidata.FDArray[j];
  1645.     if (cff_convert_charstrings(&writer, (gs_font_base *)pfd))
  1646.         cff_put_Index_header(&writer, 0, 0);
  1647.     else if (subrs_size[j] != 0)
  1648.         cff_write_Subrs(&writer, subrs_count[j], subrs_size[j], pfd);
  1649.     }
  1650.  
  1651.     /* Check the final offset. */
  1652.     offset = stell(writer.strm) - start_pos;
  1653.     if_debug2('l', "[l]End = %u => %u\n", End_offset, offset);
  1654.     if (offset > End_offset)
  1655.     return_error(offset_error("End"));
  1656.     if (offset == End_offset) {
  1657.     /* The iteration has converged.  Write the result. */
  1658.     if (writer.strm == &poss) {
  1659.         writer.strm = s;
  1660.         goto write;
  1661.     }
  1662.     } else {
  1663.     /* No convergence yet. */
  1664.     End_offset = offset;
  1665.     goto iter;
  1666.     }
  1667.  
  1668.     /* All done. */
  1669.     return 0;
  1670. }
  1671.